﻿//-----------------------------------------------------------------------
// <copyright file="ProductTests.cs" company="Transilvania University of Brasov">
//     Copyright (c) Nagy Robert. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
namespace TestDomainModel
{
    using System;

    using DomainModel;
    using Microsoft.Practices.EnterpriseLibrary.Validation;
    using NUnit.Framework;

    /// <summary>
    /// Tests for the Product class
    /// </summary>
    [TestFixture]
    public class ProductTests
    {
        /// <summary>
        /// Gets the valid product.
        /// </summary>
        private DTOProduct ValidProduct
        {
            get
            {
                return new DTOProduct
                {
                    Id = 1,
                    Description = "Description",
                    EndTime = new DateTime(2017, 1, 1),
                    Name = "Name",
                    StartTime = new DateTime(201, 12, 31),
                    Supplier = new DTOAuctioneer(),
                    InitialValue = 10.0m
                };
            }
        }
        
        /// <summary>
        /// Tests the supplier should not be null.
        /// </summary>
        [Test]
        public void TestSupplierShouldNotBeNull()
        {
            DTOProduct product = this.ValidProduct;
            product.Supplier = null;

            ValidationResults validationResults = Validation.Validate(product);
            Assert.IsFalse(validationResults.IsValid);
        }

        /// <summary>
        /// Tests the name should not be null.
        /// </summary>
        [Test]
        public void TestNameShouldNotBeNull()
        {
            DTOProduct product = this.ValidProduct;
            product.Name = null;

            ValidationResults validationResults = Validation.Validate(product);
            Assert.IsFalse(validationResults.IsValid);
        }

        /// <summary>
        /// Tests the name length should not be valid.
        /// </summary>
        /// <param name="length">The length.</param>
        [Test]
        public void TestNameLengthShoulNotBeValid([Values(0, 1, 51, 100)] int length)
        {
            string name = new string('a', length);
            DTOProduct product = this.ValidProduct;
            product.Name = name;

            ValidationResults validationResults = Validation.Validate(product);
            Assert.IsFalse(validationResults.IsValid);
        }

        /// <summary>
        /// Tests the name length should be valid.
        /// </summary>
        /// <param name="length">The length.</param>
        [Test]
        public void TestNameLengthShoulBeValid([Values(2, 25, 50)] int length)
        {
            string name = new string('a', length);
            DTOProduct product = this.ValidProduct;
            product.Name = name;

            ValidationResults validationResults = Validation.Validate(product);
            Assert.IsTrue(validationResults.IsValid);
        }

        /// <summary>
        /// Tests the description should not be null.
        /// </summary>
        [Test]
        public void TestDescriptionShouldNotBeNull()
        {
            DTOProduct product = this.ValidProduct;
            product.Description = null;

            ValidationResults validationResults = Validation.Validate(product);
            Assert.IsFalse(validationResults.IsValid);
        }

        /// <summary>
        /// Tests the description length should not be valid.
        /// </summary>
        /// <param name="length">The length.</param>
        [Test]
        public void TestDescriptionLengthShouldNotBeValid([Values(0, 1, 9, 201, 300)] int length)
        {
            string description = new string('a', length);
            DTOProduct product = this.ValidProduct;
            product.Description = description;

            ValidationResults validationResults = Validation.Validate(product);
            Assert.IsFalse(validationResults.IsValid);
        }

        /// <summary>
        /// Tests the description length should be valid.
        /// </summary>
        /// <param name="length">The length.</param>
        [Test]
        public void TestDescriptionLengthShouldBeValid([Values(10, 100, 200)] int length)
        {
            string description = new string('a', length);
            DTOProduct product = this.ValidProduct;
            product.Description = description;

            ValidationResults validationResults = Validation.Validate(product);
            Assert.IsTrue(validationResults.IsValid);
        }

        /// <summary>
        /// Tests the end time should not be before start time.
        /// </summary>
        [Test]
        public void TestEndTimeShouldNotBeBeforeStartTime()
        {
            DTOProduct product = this.ValidProduct;
            product.StartTime = new DateTime(2016, 12, 31);
            product.EndTime = new DateTime(2016, 12, 30);

            ValidationResults validationResults = Validation.Validate(product);
            Assert.IsFalse(validationResults.IsValid);
        }

        /// <summary>
        /// Tests the end time should not be equal to start time.
        /// </summary>
        [Test]
        public void TestEndTimeShouldNotBeEqualToStartTime()
        {
            DTOProduct product = this.ValidProduct;
            product.StartTime = new DateTime(2016, 12, 31);
            product.EndTime = new DateTime(2016, 12, 31);

            ValidationResults validationResults = Validation.Validate(product);
            Assert.IsFalse(validationResults.IsValid);
        }

        /// <summary>
        /// Tests the end time should be after start time.
        /// </summary>
        [Test]
        public void TestEndTimeShouldBeAfterStartTime()
        {
            DTOProduct product = this.ValidProduct;
            product.StartTime = new DateTime(2016, 12, 31);
            product.EndTime = new DateTime(2017, 1, 1);

            ValidationResults validationResults = Validation.Validate(product);
            Assert.IsTrue(validationResults.IsValid);
        }

        /// <summary>
        /// Tests the offer list should not be null.
        /// </summary>
        [Test]
        public void TestOfferListShouldNotBeNull()
        {
            DTOProduct product = this.ValidProduct;
            product.OfferList = null;

            ValidationResults validationResults = Validation.Validate(product);
            Assert.IsFalse(validationResults.IsValid);
        }

        /// <summary>
        /// Tests the offer list should be initialized empty.
        /// </summary>
        [Test]
        public void TestOfferListShouldBeInitializedEmpty()
        {
            DTOProduct product = new DTOProduct();
            Assert.AreEqual(0, product.OfferList.Count);
        }

        /// <summary>
        /// Tests the initial value should not be negative.
        /// </summary>
        /// <param name="value">The value.</param>
        [Test]
        public void TestInitialValueShouldNotBeNegative([Values(-10.0, -0.1)] decimal value)
        {
            DTOProduct product = this.ValidProduct;
            product.InitialValue = value;

            ValidationResults validationResults = Validation.Validate(product);
            Assert.IsFalse(validationResults.IsValid);
        }

        /// <summary>
        /// Tests the initial value should be positive.
        /// </summary>
        /// <param name="value">The value.</param>
        [Test]
        public void TestInitialValueShouldBePositive([Values(10.0, 0.0)] decimal value)
        {
            DTOProduct product = this.ValidProduct;
            product.InitialValue = value;

            ValidationResults validationResults = Validation.Validate(product);
            Assert.IsTrue(validationResults.IsValid);
        }
    }
}
